package com.cnware.collector;

import java.util.EventObject;

import javax.swing.event.EventListenerList;

import com.cnware.collector.listener.BaseListener;
import com.cnware.collector.listener.CollectionListener;
import com.cnware.collector.listener.SpiderListener;
import com.cnware.collector.listener.event.CollectEvent;
import com.cnware.collector.listener.event.SpiderEvent;

/**
 * 蜘蛛父类（抽象类）
 * 封装了一些必要的方法，定义了执行模板与事件调用
 * @author Wangzz
 *
 */
public abstract class Spider implements ISpider {

	/**
	 * 蜘蛛类型标识
	 * 可以考虑转移至Manager
	 */
	public static final int BAIDU = 1;
	public static final int GOOGLE = 2;
	public static final int SOUSOU = 3;
	public static final int SOUGOU = 4;
	public static final int BING = 5;
	public static final int YOUDAO = 6;
	
	/**
	 * 事件执行标识
	 */
	private static final int START_EVENT = 1;
	private static final int END_EVENT = 0;
	
	
	/**
	 * 蜘蛛配置参数
	 */
	private SpiderConfiguration param = null;
	/**
	 * 当前爬行页码
	 */
	private int pageNumb = 0;
	
	/**
	 * 蜘蛛爬行事件列表
	 */
	private EventListenerList listenerList = new EventListenerList();
	
	/* (non-Javadoc)
	 * @see com.cnware.collector.ISpider#start()
	 */
	@Override
	public void start() {
		while(this.nextPage()){
			//TODO beforeCollect
			SpiderEvent e = new SpiderEvent();
			e.setSpider(this);
			fireEvent(SpiderListener.class, START_EVENT, e);
			
			while(this.hasNext()){
				//TODO beforeCollect
				CollectEvent ee = new CollectEvent();
				ee.setSpider(this);
				ee.setCollectionURL(this.nextTarget());
				fireEvent(CollectionListener.class, START_EVENT, ee);
				
				SpiderCollection collection = this.next();
				
				//TODO afterCollect
				ee.setCollection(collection);
				fireEvent(CollectionListener.class, END_EVENT, ee);
			}
			
			//TODO afterCollect
			fireEvent(SpiderListener.class, END_EVENT, e);
		}
	}
	
	/**
	 * 注册蜘蛛监听事件
	 * @param l
	 */
	public void addSpiderListener(SpiderListener l){
		listenerList.add(SpiderListener.class, l);
	}
	
	/**
	 * 注册采集监听事件
	 * @param l
	 */
	public void addCollectionListener(CollectionListener l){
		listenerList.add(CollectionListener.class, l);
	}
	
	/**
	 * 移除蜘蛛监听事件
	 * @param l
	 */
	public void removeSpiderListener(SpiderListener l){
		listenerList.remove(SpiderListener.class, l);
	}
	
	/**
	 * 移除采集监听事件
	 * @param l
	 */
	public void removeCollectionListener(CollectionListener l){
		listenerList.remove(CollectionListener.class, l);
	}
	
	/**
	 * 调用事件回调方法
	 * @param clazz		监听器类型
	 * @param status	事件状态
	 * @param e			事件对象
	 */
	private void fireEvent(Class clazz, int status, EventObject e){
	     Object[] listeners = listenerList.getListenerList();
	     for (int i = listeners.length-2; i>=0; i-=2) {
	         if (listeners[i]==clazz) {
	        	 if(status == START_EVENT)
	        		 ((BaseListener)listeners[i+1]).startCollect(e);
	        	 else
	        		 ((BaseListener)listeners[i+1]).endCollect(e);
	         }
	     }
	}
	
	/**
	 * 抓取下一页信息，没有下一页返回false
	 * @return
	 */
	public abstract boolean nextPage();
	
	/**
	 * 抓取吓一条信息
	 * @return
	 */
	public abstract SpiderCollection next();
	
	/**
	 * 下一条待抓取的URL
	 * @return
	 */
	public abstract String nextTarget();
	
	/**
	 * 是否存在下一条抓取对象
	 * 不存在表明本页结束
	 * @return
	 */
	public abstract boolean hasNext();
	
}
